<script setup lang="ts">
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import {onBeforeUnmount, ref, shallowRef} from 'vue';
import {Editor, Toolbar} from "@wangeditor/editor-for-vue";
import type {IDomEditor} from '@wangeditor/editor';
import {removeFilesService, uploadImageService} from "@/api/server/file.ts";
import {useProblemStore} from "@/stores/problem.ts";

type InsertFnType = (url: any, alt: any) => void

// 模式
const mode = 'default'; // 或 'simple'
// 工具栏配置
const toolbarConfig = {
  excludeKeys: [
    'insertImage', // 排除“上传网络图片”选项
    'group-video', // 排除“视频”菜单
    'insertLink'
  ],
};

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef<IDomEditor | null>(null);

// 编辑器配置
const editorConfig = {
  placeholder: '请输入内容...',
  MENU_CONF: {
    uploadImage: {
      async customUpload(file: File, insertFn: InsertFnType) {
        // 允许的图片类型
        const allowedTypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];

        // 类型校验
        if (!allowedTypes.includes(file.type)) {
          return;
        }

        // 大小校验（5MB）
        if (file.size > 5 * 1024 * 1024) {
          return;
        }
        try {
          const imageFile = await uploadImageService(file) as any
          insertFn(imageFile.url, imageFile.name)
          imageAlts.value.add(imageFile.name)
        } catch (error) {
          console.error('上传图片失败：', error);
        }
      },
    },
  },
};

// 内容 HTML
const valueHtml = ref<string>('');


// 记录所有上传或插入的图片
const imageAlts = ref<Set<string>>(new Set());

const problemStore = useProblemStore()

// 编辑器创建时的回调函数
const handleCreated = (editor: IDomEditor) => {
  editorRef.value = editor; // 记录 editor 实例，重要！

  // 设置初始内容
  editor.setHtml(problemStore.content);
  valueHtml.value = problemStore.content;

  // 获取当前编辑器中的所有图片
  const imageNodes = editor.getElemsByType('image');
  imageAlts.value = new Set(imageNodes.map((node: any) => node.alt));

  // 监听图片插入事件
  editor.on('insertedImage', (imageNode: any) => {
    const imageAlt = imageNode.src;
    imageAlts.value.add(imageAlt); // 记录插入的图片
  });
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount( () => {
  const editor = editorRef.value;
  if (editor == null) return;
  editor.destroy();
});

// 获取已删除的图片
const getDeletedImages = () => {
  const editor = editorRef.value;
  if (!editor) return [];

  // 获取当前编辑器中的所有图片
  const imageNodes = editor.getElemsByType('image');
  const useImageAlts = new Set(imageNodes.map((node: any) => node.alt));

  // 对比差异，获取已删除的图片
  return Array.from(imageAlts.value).filter(
      (alt) => !useImageAlts.has(alt)
  );
};

// 删除不需要的图片, 在编辑器中，曾经插入过，但又删除了的图片
async function removeUnusedImages() {
  const unUseImageAlts = getDeletedImages();
  await removeFilesService(unUseImageAlts)
}


defineExpose({
  valueHtml,
  removeUnusedImages
})
</script>

<template>
  <div style="border: 1px solid #ccc">
    <Toolbar
        style="border-bottom: 1px solid #ccc"
        :editor="editorRef"
        :defaultConfig="toolbarConfig"
        :mode="mode"
    />
    <Editor
        style="height: 80%;width: 100%; overflow-y: hidden;"
        v-model="valueHtml"
        :defaultConfig="editorConfig"
        :mode="mode"
        @onCreated="handleCreated"
    />
  </div>
</template>

<style scoped lang="scss">
</style>
